#include "agentinthread.h"
#include "Agent/agentprotocol.h"
#include "Agent/agenttaskeventtrigger.h"
#include "Agent/agenttasktimer.h"
#include "Agent/agenttaskdatathreshtrigger.h"
#include "Agent/agenttaskdatetimetrigger.h"
#include "Agent/agentpush.h"
#include "Agent/getsetfield.h"
#include <QDebug>

AgentInThread::AgentInThread(QObject *parent) :
    QObject(parent)
{
    agentProtocol=NULL;
    agentPush=NULL;
    QTimer::singleShot(200,this,SLOT(slotInit()));
}

void AgentInThread::slotInit()
{
    agentProtocol=new AgentProtocol(this);
    agentPush=new AgentPush(this);
}

void AgentInThread::slotPacketToAgent(QByteArray packet, QString appIP, quint16 appPort)
{

    QByteArray baSN=GetSetField::getSN(packet);
    QByteArray baSNLine="\nSN:"+baSN;
    QList <QByteArray> listBaLines=packet.split('\n');
    if(listBaLines.size()<3)
    {
        emit sigSendDataToApp(agentProtocol->replyLineBadRequest()+baSNLine+"\n\n"
                              "There are too little lines!",appIP,appPort);
        return;
    }
    else if(!packet.contains("\n\n"))
    {
        emit sigSendDataToApp(agentProtocol->replyLineBadRequest()+baSNLine+"\n\n"
                 "There should be \"\\n\\n\" before payload even if the payload is empty!",appIP,appPort);
        return;
    }
    else
    {
        QList <QByteArray> listBaMethodLine=listBaLines.at(0).simplified().split(' ');

        if(listBaMethodLine.size()!=3)
        {
            emit sigSendDataToApp(agentProtocol->replyLineBadRequest()+baSNLine+"\n\n"
                 "There should be three fields in the first line!",appIP,appPort);
            return;
        }
        else
        {
            QByteArray method=listBaMethodLine.at(0).toUpper();

            if(method=="AGENTPUT")
            {
                QByteArray baURI=listBaMethodLine.at(1).toUpper();
                if(baURI.startsWith("/TIMER"))
                {
                    createAgentTaskTimer(packet,appIP,appPort);
                }
                else if(baURI.startsWith("/EVENTTRIGGER"))
                {
                    createAgentTaskEventTrigger(packet,appIP,appPort);
                }
                else if(baURI.startsWith("/DATATHRESHTRIGGER"))
                {
                    createAgentTaskDataThreshTrigger(packet,appIP,appPort);
                }
                else if(baURI.startsWith("/DATETIMETRIGGER"))
                {
                    createAgentTaskDateTimeTrigger(packet,appIP,appPort);
                }
                else
                    emit sigSendDataToApp(agentProtocol->replyLineNotFound()+"\n\n"
                         "Resource not found!",appIP,appPort);
                    return;
            }
            else if(method=="AGENTDELETE")
            {
                emit sigAgentDelete(packet,appIP,appPort);
            }
            else if(method=="AGENTGET")
            {
                emit sigAgentGet(packet,appIP,appPort);
            }
            else if(method=="AGENTWATCH")
            {
                //在自己的agentpu中也加入信息。当有新agent生成时，把这些订阅信息发给它
                agentPush->newSubscriber(baSN,appIP.toUtf8()+":"+QByteArray::number(appPort,10),packet);
                emit sigAgentWatch(packet,appIP,appPort);

                emit sigSendDataToApp(agentProtocol->replyLineOK()+baSNLine+"\n\n"
                     "Subscription registered!",appIP,appPort);
            }
            else
                emit sigSendDataToApp(agentProtocol->replyLineNotImplemented()+baSNLine+"\n\n"
                     "This method is not implemented!",appIP,appPort);
                return;
        }
    }
}

void AgentInThread::createAgentTaskTimer(QByteArray packet, QString appIP, quint16 appPort)
{
    AgentTaskTimer *agentTask=new AgentTaskTimer(agentPush->getMapIPPortReqPacket(),packet,appIP,appPort,this);
    connect(agentTask,SIGNAL(sigSendDataToApp(QByteArray,QString,quint16)),this,
            SIGNAL(sigSendDataToApp(QByteArray,QString,quint16)));
    connect(this,SIGNAL(sigAgentDelete(QByteArray,QString,quint16)),agentTask,
            SLOT(slotAgentDelete(QByteArray,QString,quint16)));
    connect(this,SIGNAL(sigAgentGet(QByteArray,QString,quint16)),agentTask,
            SLOT(slotAgentGet(QByteArray,QString,quint16)));
    //connect(this,SIGNAL(sigAgentPut(QByteArray,QString,quint16)),agentTask,
    //        SLOT(slotAgentPut(QByteArray,QString,quint16)));
    connect(this,SIGNAL(sigAgentWatch(QByteArray,QString,quint16)),agentTask,
            SLOT(slotAgentWatch(QByteArray,QString,quint16)));

    connect(agentTask,SIGNAL(sigErrorInfo(QByteArray)),this,
            SIGNAL(sigErrorInfo(QByteArray)));
    connect(agentTask,SIGNAL(sigSetIPAnalyzeIncomeDatagram(QByteArray,QHostAddress,quint16)),
            this,SIGNAL(sigSetIPAnalyzeIncomeDatagram(QByteArray,QHostAddress,quint16)));
}

void AgentInThread::createAgentTaskEventTrigger(QByteArray packet, QString appIP, quint16 appPort)
{
    AgentTaskEventTrigger *agentTask=new AgentTaskEventTrigger(agentPush->getMapIPPortReqPacket(),packet,appIP,appPort,this);
     connect(agentTask,SIGNAL(sigSendDataToApp(QByteArray,QString,quint16)),this,
             SIGNAL(sigSendDataToApp(QByteArray,QString,quint16)));
     connect(this,SIGNAL(sigAgentDelete(QByteArray,QString,quint16)),agentTask,
             SLOT(slotAgentDelete(QByteArray,QString,quint16)));
     connect(this,SIGNAL(sigAgentGet(QByteArray,QString,quint16)),agentTask,
             SLOT(slotAgentGet(QByteArray,QString,quint16)));
    // connect(this,SIGNAL(sigAgentPut(QByteArray,QString,quint16)),agentTask,
     //        SLOT(slotAgentPut(QByteArray,QString,quint16)));
     connect(this,SIGNAL(sigAgentWatch(QByteArray,QString,quint16)),agentTask,
             SLOT(slotAgentWatch(QByteArray,QString,quint16)));

     connect(agentTask,SIGNAL(sigErrorInfo(QByteArray)),this,
             SIGNAL(sigErrorInfo(QByteArray)));
     connect(agentTask,SIGNAL(sigSetIPAnalyzeIncomeDatagram(QByteArray,QHostAddress,quint16)),
             this,SIGNAL(sigSetIPAnalyzeIncomeDatagram(QByteArray,QHostAddress,quint16)));
}

void AgentInThread::createAgentTaskDataThreshTrigger(QByteArray packet, QString appIP, quint16 appPort)
{
    AgentTaskDataThreshTrigger *agentTask=new AgentTaskDataThreshTrigger(agentPush->getMapIPPortReqPacket(),packet,appIP,appPort,this);
    connect(agentTask,SIGNAL(sigSendDataToApp(QByteArray,QString,quint16)),this,
            SIGNAL(sigSendDataToApp(QByteArray,QString,quint16)));
    connect(this,SIGNAL(sigAgentDelete(QByteArray,QString,quint16)),agentTask,
            SLOT(slotAgentDelete(QByteArray,QString,quint16)));
    connect(this,SIGNAL(sigAgentGet(QByteArray,QString,quint16)),agentTask,
            SLOT(slotAgentGet(QByteArray,QString,quint16)));
    //connect(this,SIGNAL(sigAgentPut(QByteArray,QString,quint16)),agentTask,
    //        SLOT(slotAgentPut(QByteArray,QString,quint16)));
    connect(this,SIGNAL(sigAgentWatch(QByteArray,QString,quint16)),agentTask,
            SLOT(slotAgentWatch(QByteArray,QString,quint16)));

    connect(agentTask,SIGNAL(sigErrorInfo(QByteArray)),this,
            SIGNAL(sigErrorInfo(QByteArray)));
    connect(agentTask,SIGNAL(sigSetIPAnalyzeIncomeDatagram(QByteArray,QHostAddress,quint16)),
            this,SIGNAL(sigSetIPAnalyzeIncomeDatagram(QByteArray,QHostAddress,quint16)));
}

void AgentInThread::createAgentTaskDateTimeTrigger(QByteArray packet, QString appIP, quint16 appPort)
{
    AgentTaskDateTimeTrigger *agentTask=new AgentTaskDateTimeTrigger(agentPush->getMapIPPortReqPacket(),packet,appIP,appPort,this);
    connect(agentTask,SIGNAL(sigSendDataToApp(QByteArray,QString,quint16)),this,
            SIGNAL(sigSendDataToApp(QByteArray,QString,quint16)));
    connect(this,SIGNAL(sigAgentDelete(QByteArray,QString,quint16)),agentTask,
            SLOT(slotAgentDelete(QByteArray,QString,quint16)));
    connect(this,SIGNAL(sigAgentGet(QByteArray,QString,quint16)),agentTask,
            SLOT(slotAgentGet(QByteArray,QString,quint16)));
    //connect(this,SIGNAL(sigAgentPut(QByteArray,QString,quint16)),agentTask,
    //        SLOT(slotAgentPut(QByteArray,QString,quint16)));
    connect(this,SIGNAL(sigAgentWatch(QByteArray,QString,quint16)),agentTask,
            SLOT(slotAgentWatch(QByteArray,QString,quint16)));

    connect(agentTask,SIGNAL(sigErrorInfo(QByteArray)),this,
            SIGNAL(sigErrorInfo(QByteArray)));
    connect(agentTask,SIGNAL(sigSetIPAnalyzeIncomeDatagram(QByteArray,QHostAddress,quint16)),
            this,SIGNAL(sigSetIPAnalyzeIncomeDatagram(QByteArray,QHostAddress,quint16)));
}

AgentInThread::~AgentInThread()
{

}
